using System;
using System.Collections;

using GURUCORE.Framework.Core;
using GURUCORE.Framework.Core.Proxy;
using GURUCORE.Framework.Business;
using GURUCORE.Framework.Business.Security;
using GURUCORE.Framework.Core.Data;
using GURUCORE.Framework.DataAccess;
using GURUCORE.Framework.DataAccess.ORMapping;
using GURUCORE.Framework.DataAccess.ORMapping.CriteriaMapping;

using GURUCORE.Portal.Service.Business.DTO;

namespace GURUCORE.Portal.Service.Business
{
    public class ActiveSessionService : BusinessService, IActiveSessionService
	{
        /// <summary>
        /// p_dto needs to have SessionGUID and WebsiteID, this is minimum info what website give to PortalServer
        /// This function will update the online status into Database table Portal_ActiveSession        
        /// </summary>
        /// <param name="p_dto"></param>
        /// <returns>
        /// It will return array of ActiveSession, in which p_dto.UserID is taking part in
        /// If p_dto.UserID is not take part in anything, it will return null
        /// </returns>
        [TransactionBound]
        public virtual ActiveSessionDTO[] SynchronizeActiveSession(ActiveSessionDTO p_dto)
        {
            TableMapper<ActiveSessionDTO> tbl = new TableMapper<ActiveSessionDTO>();

            #region update the session status
            // PERFORMANCE: Ta chi can chay mot cau: update set LastActive = GetDate() where SessionGUID = () and WebsiteGUID = ()
            // khong can phai lam lang nhang nhu the nay
            //string sConnectionString = DataAccessContext.GetDataAccessContext().GetConnection().ConnectionString;
            //// SQL: update  PORTAL_ACTIVESESSION set LastActive = GetDate() where SessionGUID = () and WebsiteGUID = () 
            //DataHelper.SetDSN(sConnectionString);
            //DataHelper.ExecuteNonQuery("update PORTAL_ACTIVESESSION set LastActive = GetDate(),  " +
            //    " IP = " + +
            //        " " +
            //            " " +    " " +
            //                " " +
            //                    " " +
            //                        " " +
            //"where SessionGUID = '"+p_dto.SessionGUID+"' and WebsiteGUID = '"+p_dto.WebsiteGUID+"' "); 

            
            Expression expSess = new Expression(ActiveSessionDTO.SESSIONGUID_FLD, Operator.Eq, p_dto.SessionGUID);
			Expression expWeb = new Expression(ActiveSessionDTO.WEBSITEGUID_FLD, Operator.Eq, p_dto.WebsiteGUID);
            Expression exp = new Expression(expSess, Operator.And, expWeb);

            Criteria crt = new Criteria(exp, null);
            DTOCollection<ActiveSessionDTO> arr = tbl.GetObjects(crt);

            if (arr.Count > 0)   // if existed session
            {
                // update the newest status
                p_dto.ActiveSessionID = arr[0].ActiveSessionID;
                tbl._SaveObject(p_dto);
            }
            else // if not, create a new session record for this sessionID and WebsiteID
            {
                try
                {
                    tbl._AddObject(p_dto);
                }
                catch { }
            }

            DeleteExpireSession();

            #endregion update the session status

            #region return all session this UserID takes part in
            if (p_dto.UserID <= 0)  // PERFORMANCE: short circuit
            {
                return null;
            }

            Expression expUserID = new Expression(ActiveSessionDTO.USERID_FLD, Operator.Eq, p_dto.UserID);
            Criteria crtGet = new Criteria(expUserID, null);
            DTOCollection<ActiveSessionDTO> carr = tbl.GetObjects(crtGet);
            
            if (carr.Count > 0)
            {
                return carr.ToArray();
            }
            else
            {
                return null;
            }

            #endregion
        }

		[NonDelegated]
        private void DeleteExpireSession()
        {
            try
            {
                // DONE: delete all expire session
                ExpressionSQL exp = new ExpressionSQL("PORTAL_ACTIVESESSION.LastActive < DateAdd(s, -3600, GetDate() )");                
                DAU._DeleteObjects<ActiveSessionDTO>(exp);
            }
            catch // (Exception ex)
            {
                // ex.ToString();
            }
        }

	}
}
